﻿using System.Collections;

public class FiniteStateMachine {
	
	public delegate void delegateInit();
	public delegate void delegateUpdate();
	public delegate void delegateFinish();
	
	public class States
	{
		public delegateInit 	m_InitFnc = null;
		public delegateUpdate 	m_UpdateFnc = null;
		public delegateFinish 	m_FinishFnc = null;
	}
	protected int m_CurrentStateIndex;
	
	States m_CurrentState;
	private ArrayList m_StateList = new ArrayList();
	int m_nextStateIndex;
	
	public FiniteStateMachine()
	{
		m_nextStateIndex = -1;
	}
	
	public int StateIndex { get{ return this.m_CurrentStateIndex; } }
	
	public int createState( delegateInit _initFnc, delegateUpdate _updateFnc, delegateFinish _finishFnc )
	{
	
		States _newState = new States();
		_newState.m_InitFnc = _initFnc;
		_newState.m_UpdateFnc = _updateFnc;
		_newState.m_FinishFnc = _finishFnc;
		m_StateList.Add(_newState);
		
		if( m_StateList.Count == 1 )
		{
			m_CurrentStateIndex = 0;
			m_CurrentState = _newState;
		}
		return m_StateList.Count - 1;
	}
	
	public void changeState(int _idx )
	{
		m_nextStateIndex = _idx;
	}
	
	public void setState( int _idx )
	{
		if( _idx < m_StateList.Count && _idx >= 0 )
		{
			if( m_CurrentState != null && m_CurrentState.m_FinishFnc != null )
			{
				m_CurrentState.m_FinishFnc();
			}
			
			States _nextState = m_StateList[_idx] as States;
			
			if( _nextState.m_InitFnc != null )
			{
				_nextState.m_InitFnc();
			}
			
			m_CurrentStateIndex = _idx;
			m_CurrentState = _nextState;
		}
	}

    public void Update()
    {
        m_CurrentState.m_UpdateFnc();
    }

    public void LateUpdate()
	{
		if( m_nextStateIndex != -1 )
		{
			if( m_nextStateIndex < m_StateList.Count && m_nextStateIndex >= 0 )
			{
				if( m_CurrentState != null && m_CurrentState.m_FinishFnc != null )
				{
					m_CurrentState.m_FinishFnc();
				}
				
				States _nextState = m_StateList[m_nextStateIndex] as States;
				
				if( _nextState.m_InitFnc != null )
				{
					_nextState.m_InitFnc();
				}
				
				m_CurrentStateIndex = m_nextStateIndex;
				m_CurrentState = _nextState;
			}
			
			m_nextStateIndex = -1;
		}
		
	}
	
}
